// ======any类型，在申明变量指定数据类型的时候，TS默认指定是any类型，any类型TS会关闭数据类型的校验，与JS无异====
let a:any
a = 123
a = true
console.log("any类型：",a)


// ====与any类型很相似的是未知类型 unknown,不同的是，unknown没有关闭数据类型的校验=====
let b : unknown
b = 123
b = true
console.log("unknown类型：",b)

let c:string
c = a  // 正确
// c = b // 报错

console.log("any类型 vs$ unknown类型：",typeof c)



// ======断言类型，告诉解析器变量的实际类型========

let d = "断言类型"

/* 
    写法一 
*/
let e = d as string

/*  
    写法二 
*/
let f = <string> d
console.log("断言方法一:",e)
console.log("断言方法二:",f)


// ===== void 表示函数没有返回值,表示空值 =====
function myFn ():void {
    
}

// ===== never 表示用于没有结果 ===== 
// function myFn2():never {
//     throw new Error("错误信息！！")
// }
// myFn2()


// ======= 定义对象，指定属性  ========
/* 
    表示 obj1对象 必须有name属性，age属性可选，但不能再存在其他属性 
*/
let obj1:{name:string,age?:number}
obj1 = {
    name: "李白",
    age: 200
}

// 表示 obj2对象 必须有name属性，还可选其他属性,其属性值可以是任意类型
let obj2: {name:string,[proName: string]:any}
obj2 = {
    name: "李白",
    age: 200,
    vocation: "著名诗人"
}


// ======== 定义函数结构的类型申明 ========
/*  
    表示 函数的参数必须是两个number类型，并返回的是number类型
 */
let myFn3: (arg1:number,arg2:number) => number
myFn3 = function(arg1:number,arg2):number{
    var result = arg1 + arg2
    return result
}
console.log("函数结构类型申明：",myFn3(1,5))


// ========= 定义 数组的数据类型 ==========

/*  
    方法一
    表示 arr1数组的元素只能是number类型 
 */
let arr1:number[]
arr1 = [1,5]

/* 
    方法二：
    表示 arr2数组的元素只能是number类型
*/
let arr2: Array<number>
arr2 = [1,2]


// =============== 元组 =============
/* 
    TS 新增的，JS中并并不具有
    表示 数组的长度固定
*/
let arr3: [string,string]
arr3 = ["元素1","元素2"]
console.log("元组：",arr3)



// ================= 枚举 =============
/* 
    TS新增的，JS中不具有
    把多种可能性列出来
*/
enum Gemder {
    man,
    gir
}

let obj3: {name:string,gender: Gemder,[proName:string]:any}
obj3 = {
    name: "李白",
    gender: Gemder.man,
    age:200

}

console.log("枚举：",obj3)


// ==========  类型别名 ===============

/* 
    定义一个类型别名 string或者number类型的
    语法： type 别名 = 类型
*/
type mytype1 = string |number
let val1:mytype1
val1 = 1

/* 
    定义类型mytype2 只能是 1 或者 2
    val2只能赋值 1 或者 2
*/
type mytype2 = 1 | 2
let val2:mytype2
val2 = 2